/*
 * $Id: om-numberfield.js,v 1.69 2012/03/15 06:14:47 linxiaomin Exp $
 * operamasks-ui omNumberField 1.2
 *
 * Copyright 2011, AUTHORS.txt (http://ui.operamasks.org/about)
 * Dual licensed under the MIT or LGPL Version 2 licenses.
 * http://ui.operamasks.org/license
 *
 * http://ui.operamasks.org/docs/
 *
 * Depends:
 *  om-core.js
 */
(function($) {
    
    // 设置小数精度
    var fixPrecision = function(value, c, p) {
        var v = value.indexOf(".");       
        if (isNaN(value) && value != ".") {
            for (; isNaN(value);) {
                value = value.substring(0, value.length - 1);
            }
        }
        if(!p.allowNegative && value.indexOf("-")!= -1){
        	var array=value.split("-");
        	value=array.join("");
        }
        if(!p.allowDecimals&&v!=-1 || value[value.length-1]==='.'){
            return value.substring(0, v);
         }
        if(v!=-1){
            value=value.substring(0,v+p.decimalPrecision+1);
        }
        return value.length > 0 ? parseFloat(value) : "";
    };

    /**
     * 将输入数值字符串转换为千分位形式
     */
    var commafy = function (numStrVal, allowDecimals, decimalPrecision) {
        if (decimalPrecision == undefined || decimalPrecision == null || isNaN(decimalPrecision)) {
            decimalPrecision = 2;//默认2位小数
        }
        var s = parseFloat(numStrVal); //获取小数型数据
        s += "";

        if (s.indexOf(".") == -1) s += ".0";//如果没有小数点，在后面补个小数点和0
        //获取小数位部分
        var pointPart = s.substring(s.lastIndexOf(".")+1, s.length);
        while (pointPart.length < decimalPrecision) {
            pointPart += "0";
        }
        s = s.substring(0,s.lastIndexOf("."))+"."+pointPart;

        while (/\d{4}(\.|,)/.test(s)) {
            //符合条件则进行替换
            s = s.replace(/(\d)(\d{3}(\.|,))/, "$1,$2");//每隔3位添加一个，
        }

        if (!allowDecimals) {//由于上面正则需要小数点,因此这里单独处理整数情况
            s=s.substring(0,s.length-(decimalPrecision+1));
        }
        return s;

    };

	/**
	 * 获取千分位形式字符串数值
	 */
	var uncommafy = function (num) {
		return parseFloat(num.replace(/,/gi,''));
	};

    /** 
     * @name omNumberField
     * @class 数字输入框组件，只能输入数字，字符自动过滤掉。<br/>
     * @constructor
     * @description 构造函数. 
     * @param p 标准config对象：{}
     * @example
     * $('numberFielddiv').omNumberField({decimalPrecision:3});
     */
    $.omWidget("om.omNumberField", {
        options: /** @lends omNumberField.prototype */ 
        {
            /**
             * 是否允许输入小数。
             * @default true
             * @type Boolean
             * @example
             * $('#input').omNumberField({allowDecimals:true});
             */
            allowDecimals: true,  //是否允许输入小数
            /**
             * 是否允许输入负数。
             * @default true
             * @type Boolean
             * @example
             * $('#input').omNumberField({allowNegative:true});
             */
            allowNegative: true,  //是否允许输入负数
            /**
             * 精确到小数点后几位。
             * @default 2
             * @type Number
             * @example
             * $('#input').omNumberField({decimalPrecision:2});
             */
            decimalPrecision: 2, //精确到小数点后几位
            /**
             * 是否禁用组件。
             * @default false
             * @type Boolean
             * @example
             * $('#input').omNumberField({disabled:true});
             */
            disabled: false,
            /**
             * 在输入框失去焦点时触发的方法。
             * @event
             * @param value 当前输入框的值
             * @param event jQuery.Event对象
             * @default emptyFn
             * @example
             * $('#input').omNumberField({onBlur:function(value,event){alert('now the value is'+value);}});
             */
            onBlur: function(value){},
            /**
             * 是否只读。
             * @default false
             * @type Boolean
             * @example
             * $('#input').omNumberField({readOnly:true});
             */
            readOnly: false,
            milliabled : true,//是否显示千分位
            ronly: false //增加一个只读状态方法,非disabled
        },

        _create : function() {
            // 允许输入的字符
            var options = this.options,
            	self = this;
            //转换默认的数值为千分位
            if (options.milliabled) {
            	var thisEl = this.element;
            	if (thisEl.val()!='') {
            		thisEl.val(commafy(thisEl.val(),options.allowDecimals,options.decimalPrecision));
            	} else {
                    self._defaultVal();
                }
            }
            	/*原样式 om-numberfield om-widget om-state-default om-state-nobg*/
            this.element.addClass("om-numberfield om-widget om-state-nobg").css("ime-mode" , "disabled");
			
            this.element.keypress(function(e) {
                if (e.which == null && (e.charCode != null || e.keyCode != null)) {
                    e.which = e.charCode != null ? e.charCode : e.keyCode;
                }
                var k = e.which;
                if (k === 8 || (k == 46 && e.button == -1) || k === 0) {
                    return;
                }
                var character = String.fromCharCode(k);
                $.data(this,"character",character);
                var allowed = $.data(this, "allowed");
                if (allowed.indexOf(character) === -1||($(this).val().indexOf("-") !== -1 && character == "-")
                        || ($(this).val().indexOf(".") !== -1 && character == ".")) {
                    e.preventDefault();
                }
            }).focus(function(){
            	var n = $(this);
            	n.addClass('om-state-focus');
            	if (options.milliabled) {
					if (n.val() !== '')
						n.val(uncommafy(n.val())); //TODO val导致光标前移;FIREFOX无法复制 粘贴
            	}
            }).blur(function(e){
            	var n = $(this);
                n.removeClass('om-state-focus');
            	var character = $.data(this,"character");
                this.value=fixPrecision(this.value, character, options);
                if (options.milliabled) {
					if (this.value !== "") {
						this.value = commafy(this.value,options.allowDecimals,options.decimalPrecision);
						n.val(this.value);
					} else {
                        self._defaultVal();
                    }
                }
                self._trigger("onBlur",e,parseFloat(uncommafy(this.value)));
            }).keydown(function(e){
            	self._checkLast(this);
            	
            	//Chrome并不支持css属性ime-mode,无法阻止拼音输入，但当使用输入法时，事件的e.which===229恒成立.
            	if(229 === e.which){
            		e.preventDefault();
            	}
            }).keyup(function(e){//在Chrome中文输入法下，输入  ，。等字符不会触发input框的keypress事件
            	self._checkLast(this);
            });
        },

        //千分位时,初始化或清空输入值,格式化成0.00***
        _defaultVal:function(){
            var options = this.options;
            if (options.allowDecimals) {
                var declen = options.decimalPrecision;
                var num = '0.';
                for (var i=0;i<declen;i++) {
                    num+='0';
                }
                this.element.val(num);
            } else {
                this.element.val("0");
            }
        },
		
        _init : function() {
            var $ele = this.element,
                opts = this.options;
            
            if (typeof opts.disabled !== "boolean") {
                opts.disabled = $ele.attr("disabled");
            }

            if (opts.readOnly) {
                $ele.attr("readonly","readonly");
            }

            var character = $.data($ele[0], "character");
            
            this._buildAllowChars();
            
            if (opts.disabled) {
                this.disable();
            } else {
                this.enable();
            }
        },
        
		_checkLast : function(self){
			var v = self.value,
        		len = v.length;
        	if(v && $.data(self,"allowed").indexOf(v.charAt(len-1))===-1
        		|| v.indexOf('.') != v.lastIndexOf('.')
        		|| v.indexOf('-') != v.lastIndexOf('-')){
        		self.value = v = v.substring(0 , (len--)-1);
        	}
		},
        _buildAllowChars : function() {
            var allowed = "0123456789";

            // 允许输入的字符
            if (this.options.allowDecimals) {
                allowed = allowed + ".";
            }
            if (this.options.allowNegative) {
                allowed = allowed + "-";
            }
            if (this.options.readOnly) {
                allowed = "";
            }
            $.data(this.element[0], "allowed", allowed);
        },
        /**
         * 禁用组件。
         * @name omNumberField#disable
         * @function
         * @example
         * $('#input').omNumberField("disable")
         */
        disable : function() {
            this.element.attr("disabled", true)
                    .addClass("om-numberfield-disabled");
        },
        /**
         * 启用组件。
         * @name omNumberField#enable
         * @function
         * @example
         * $('#input').omNumberField("enable")
         */
        enable : function() {
            this.element.attr("disabled", false)
                    .removeClass("om-numberfield-disabled");
        },
        ronly: function(isR) {
        	if (isR) {//设置只读
        		this.element.attr("readonly", "readonly").addClass('om_readonly')
                    .addClass("om-numberfield-disabled");
        	} else {//取消只读
        		this.element.removeAttr("readonly").removeClass('om_readonly')
                    .removeClass("om-numberfield-disabled");
        	}
        },
        value:function (v) {
            var options = this.options;
            if (v !== undefined) {
                $(this.element).val(commafy(v, options.allowDecimals,options.decimalPrecision));
            } else {
                return uncommafy($(this.element).val());
            }
        }
    });

    $.omNumberField = $.omNumberField || {};
    $.omNum = $.omNumberField;
    $.extend($.omNum, {
        commafy : commafy,
        uncommafy : uncommafy
    });
})(jQuery);